<template>
  <xy-page title="菜单列表">
    <xy-search class="mgt20">
      <el-form inline :model="searchFilter" label-width="70px">
        <el-form-item label="系统" prop="">
          <el-select v-model="appId" placeholder="请选择系统">
            <el-option v-for="item in appList" :key="item.id" :label="item.cnName" :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="right">
        <el-button plain @click="resetForm">重置条件</el-button>
      </div>
    </xy-search>
    <div>
      <div style="text-align:right;" v-if="appId">
       <!-- <el-button @click="syncMenuResource" type="warning" size="small" v-auth="'AUTH_MENU-SAVE'">同步所有菜单资源</el-button> -->
        <xy-save v-model="isResetMenu" type="plane" size="small" @click="resetMenu" text="重置中..." v-auth="'AUTH_MENU-SAVE'">重置菜单</xy-save>
        <xy-save v-model="isSave" type="primary" size="small" @click="save" text="保存中..." v-auth="'AUTH_MENU-SAVE'">保存</xy-save>
      </div>
      <div style="display:inline-block;width:49%;vertical-align:top;">
        <el-tree :data="treeData" node-key="id" :props="defaultProps" default-expand-all :allow-drop="allowDrop" :allow-drag="allowDrag" empty-text="请选择系统" :expand-on-click-node="false" :highlight-current="true" @node-drag-end="handleDragEnd" @node-click="nodeClick"
          draggable>

          <span class="custom-tree-node" slot-scope="{ node, data }">
            <span :class="{lineThrough:data.isActive == 0,green:data.id == 0}">{{ node.label }}
              <span v-if="data.level == 3" :class="{green:data.resources.length!==0,red:data.resources.length == 0}">({{data.resources.length}})</span>
              </span>
            <span class="node-button">
              <el-button type="text" size="mini" @click.stop="() => appendSub(data)" v-if="data.level < 3" v-auth="'AUTH_MENU-SAVE'">
                子菜单
              </el-button>
              <el-button type="text" size="mini" @click.stop="() => append(node, data)" v-if="data.id != -1" v-auth="'AUTH_MENU-SAVE'">
                同级菜单
              </el-button>
              <el-button type="text" size="mini" @click.stop="() => remove(node, data)" v-if="data.id != -1" v-auth="'AUTH_MENU-SAVE'">
                删除
              </el-button>
            </span>
          </span>

        </el-tree>
      </div>
      <div style="display:inline-block;width:49%;vertical-align:top;" v-if="typeof menu.id != 'undefined'">
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require"></span>菜单id:</label>
          <el-input v-model="menu.id" type="text" :disabled="true" placeholder="菜单id"></el-input>
        </div>
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require"></span>排序:</label>
          <el-input v-model="menu.sort" type="text" :disabled="true" placeholder="排序"></el-input>
        </div>
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require">*</span>图标:</label>
          <el-input v-model="menu.icon" type="text" placeholder="请输入图标"></el-input>
        </div>
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require">*</span>菜单名字:</label>
          <el-input v-model="menu.name" type="text" placeholder="请输入菜单名字"></el-input>
        </div>
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require"></span>扩展字段:</label>
          <el-input v-model="menu.ext" type="text" placeholder="扩展字段"></el-input>
        </div>
        <div class="form-row form-group " v-show="menu.level == 1">
          <label class="text-right">
            <span class="require"></span>菜单显示表达式:</label>
          <el-input v-model="menu.showReg" type="text" placeholder="菜单显示表达式"></el-input>
        </div>
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require">*</span>菜单地址:</label>
          <el-input v-model="menu.url" type="text" placeholder="请输入菜单地址"></el-input>
        </div>
        <div class="form-row form-group ">
          <label class="text-right">
            <span class="require">*</span>是否显示:</label>
          <div>
            <el-radio v-model="menu.isActive" :label="1">显示</el-radio>
            <el-radio v-model="menu.isActive" :label="0">隐藏</el-radio>
          </div>
        </div>
        <div v-show="menu.level == 3">
          <div class="form-row form-group ">
            <div class="form-line"></div>
          </div>
          <div class="form-row form-group ">
            <el-button type="primary" @click="qucikSelect()">同名资源</el-button>
          </div>
            <el-transfer filterable
            :filter-method="filterResourceMethod" 
            filter-placeholder="请输入资源名称" 
            v-model="menu.resources" 
            :data="menuResources"
            :titles="['全部资源', '关联资源']"
            :props="{
              key: 'id',
              label: 'name'
            }"
            >
            </el-transfer>
          </div>
      </div>

    </div>
  </xy-page>

</template>

<script>
  export default {
    name: "auth-menu-list",
    data() {
      return {
        searchFilter: {},
        appId: null,
        appList: [],
        menuResources:[],
        treeData: [],
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        isResetMenu: false,
        isSave: false,
        menu: {}
      }
    },
    methods: {
      appendSub(data) {
        var menu = {
          id: 0,
          isActive: 1,
          name: "新建菜单",
          url: "",
          resources:[],
          children: []
        };
        data.children.push(menu);
        this.setLevel(this.treeData);
        this.menu = menu;
        var tmp = this.treeData;
        this.treeData = [];
        this.$nextTick(() => {
          this.treeData = tmp;
        });
      },
      remove(node, data) {
        this.$xyConfirm("确认是否删除，删除后数据将无法恢复？", () => {
          var index = -1;
          node.parent.data.children.forEach((item, i) => {
            if (item === data) {
              index = i;
            }
          });
          if (index == -1) return;
          node.parent.data.children.splice(index, 1);
          this.setLevel(this.treeData);
          if (this.menu === data) {
            this.menu = {};
          }
        });
      },
      append(node) {
        var menu = {
          id: 0,
          isActive: 1,
          name: "新建菜单",
          url: "",
          resources:[],
          children: []
        };
        node.parent.data.children.push(menu);
        this.setLevel(this.treeData);
        this.menu = menu;

      },
      handleDragEnd() {
        this.setLevel(this.treeData);
      },
      allowDrop(draggingNode, dropNode, type) {
        if (dropNode.data.id == -1) {
          return false;
        }
        if (dropNode.data.level == 3) {
          return type !== 'inner';
        }
        return true;
      },
      allowDrag(draggingNode) {
        if (draggingNode.data.id == -1) {
          return false;
        }
        return true;
      },
      nodeClick(menu) {
        if (menu.id == -1) {
          menu = {};
        }
        this.menu = menu;
      },
      setLevel(data, level, sort) {
        level = level || 0;
        sort = sort || 0;
        if (!data || data.length == 0) {
          return sort;
        }
        data.forEach(item => {
          item.level = level;
          item.appId = this.appId;
          item.sort = sort++;
          item.children = item.children || [];
          sort = this.setLevel(item.children, level + 1, sort);
        });
        return sort;
      },
      resetMenu() {
        this.$xyConfirm("确认是否重置菜单，重置后修改的数据将无法恢复？", () => {
          this.isResetMenu = true;
          this.resetData(() => {
            this.isResetMenu = false;
          });
        });
      },
      resetData(cb) {
        this.menu = {};
        this.treeData = [];
        this.$nextTick(() => {
          this.$get("/admin/auth/instance/authMenu/list.do", {
            data: {
              appId: this.appId
            },
            success: res => {
              this.treeData = res.object || [];
              this.treeData = [{
                id: -1,
                name: "全部菜单",
                children: this.treeData
              }];
              this.initMenuResource(this.treeData);
              this.setLevel(this.treeData);
              cb && cb();
            }
          })
        });

      },

      initMenuResource(menus){
        if(!menus || menus.length == 0){
          return;
        }
        menus.forEach(menu => {
          menu.resources = menu.resources || "";
          menu.resources = menu.resources.replace(/^,/,"").replace(/,$/,"");
          if(menu.resources){
            menu.resources = menu.resources.split(",");
            for(let i=0;i<menu.resources.length;i++){
              menu.resources[i] = Number(menu.resources[i]);
            }
          }else{
            menu.resources = [];
          }
          this.initMenuResource(menu.children);
        });
      },

      setResource(menus){
        if(!menus || menus.length == 0){
          return;
        }
        menus.forEach(menu => {
          menu.resources = menu.resources || [];
          menu.resources =  menu.resources.join(",");
          if(menu.resources){
             menu.resources = ","+ menu.resources +",";
          }
          this.setResource(menu.children);
        });
      },
      save() {
        this.setLevel(this.treeData);
        this.isSave = true;
        var data = JSON.parse(JSON.stringify(this.treeData[0]));
        this.setResource([data]);
        this.$postStream("/admin/auth/instance/authMenu/save.do", {
          data: data,
          success: (res) => {
            this.isSave = false;
            if (!res.success) {
              return this.$message.error(res.message);
            }
            this.$message.success(res.message);
            this.resetData();
          }
        });
      },
      resetForm() {
        this.$postStream("/admin/auth/instance/authApp/list.do", {
          data: {},
          success: res => {
            if (res.success) {
              this.appList = res.object.list || [];
              this.appId = "";
              this.treeData = [];
            } else {
              this.$message.error(res.message);
            }
          },
          error: () => {}
        });
      },
      filterResourceMethod(query, item){
        return item.name.indexOf(query) > -1;
      },
      getMenuResources(){
        this.$postStream("/admin/auth/instance/authResources/listForApp.do", {
          data: {
            appId: this.appId
          },
          success: res => {
            if (res.success) {
              this.menuResources = res.object || [];
            } else {
              this.$message.error(res.message);
            }
          },
          error: () => {}
        });
      },
      syncMenuResource(){
        var tmpTreeData = this.treeData[0].children;
        tmpTreeData.forEach(item1 => {
          item1.children.forEach(item2 => {
            item2.children.forEach(item3 => {
              this.qucikSelect(item3);
            });
          });
        });
      },
      qucikSelect(menu){
        menu = menu || this.menu;

        if(!menu || !menu.name) return;
        
        var resources = [];
        this.menuResources.forEach(resource => {
          if(resource.name.indexOf(menu.name+"-") != -1){
            resources.push(resource.id);
          }
        });
        menu.resources = menu.resources || [];
        resources.forEach(id => {
          if(menu.resources.indexOf(id) == -1){
            menu.resources.push(id);
          }
        });
        var map = {};
        menu.resources.forEach(id => {
          map[id] = id;
        });
        menu.resources = [];
        for(let key in map){
          menu.resources.push(Number(key));
        }
      },
    },
    mounted() {
      this.resetForm();
    },
    watch: {
      appId() {
        if (!this.appId) {
          return;
        }
        this.resetData();
        this.getMenuResources();
      }
    }
  }
</script>

<style lang="scss">
  .lineThrough {
    text-decoration: line-through
  }

  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 10px;
  }

  .form-line {
    height: 1px;
    background-color: #dcdfe6;
  }
  .el-transfer__buttons{
    padding:0 6px;
  }
  .el-transfer__button{
    border-radius:50%;
    font-size:0;
    min-width:0;
    padding:0;
    height: 34px;
    width: 34px;
    line-height: 34px;
  }
</style>